package com.zmn.oms.zmn.business.impl.quotation3;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zmn.base.common.data.common.dro.fault.FaultMaintainRelationDRO;
import com.zmn.base.common.data.common.dro.maintainitem.MaintainItemDRO;
import com.zmn.base.common.data.common.dro.maintainoption.OptionRelationDRO;
import com.zmn.base.common.data.dubbo.interfaces.fault.FaultMaintainRelationListRemoteService;
import com.zmn.base.common.data.dubbo.interfaces.maintainitem.MaintainItemListRemoteService;
import com.zmn.base.plat.engine.common.constant.PlatEngineConsts;
import com.zmn.base.price.common.constant.ItemAdditionConst;
import com.zmn.base.price.common.constant.ItemCellConst;
import com.zmn.base.price.common.constant.ItemTypeConst;
import com.zmn.base.price.common.constant.WarrantyConst;
import com.zmn.base.price.common.dro.item.ItemPartsDRO;
import com.zmn.base.price.common.dto.item.ItemCellDRO;
import com.zmn.base.price.common.dto.item.ItemDRO;
import com.zmn.base.price.common.dto.item.ItemQuoteQuery;
import com.zmn.base.price.common.dto.item.ItemWarrantyDetailDRO;
import com.zmn.base.price.dubbo.interfaces.calculate.ItemPriceRemoteService;
import com.zmn.base.price.dubbo.interfaces.calculate.MeterFlow3RemoteService;
import com.zmn.base.price.dubbo.interfaces.item.ItemPartsRemoteService;
import com.zmn.base.price.dubbo.interfaces.item.ItemWarrantyRemoteService;
import com.zmn.base.product.common.dto.categ.CategServProductGroupDRO;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategRelationFaultImageListRemoteService;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategServProductListRemoteService;
import com.zmn.coa.common.dio.ArtificialPromDIO;
import com.zmn.coa.common.util.DubboConsts;
import com.zmn.coa.dubbo.impl.interfaces.amount.OrderAmountRemoteService;
import com.zmn.coa.dubbo.impl.interfaces.order.discount.OrderDiscountRemoteService;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountBService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountCalcBService;
import com.zmn.oms.business.interfaces.orderamount.OrderDiscountCalcBService;
import com.zmn.oms.business.interfaces.orderfinalpricequotation.OrderFinalPriceQuotationBService;
import com.zmn.oms.business.interfaces.part.OrderPartBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dio.quotation3.*;
import com.zmn.oms.common.dro.finalpricequotation.OrderFinalPriceQuotationDRO;
import com.zmn.oms.common.dro.normal.pay.AmountDRO;
import com.zmn.oms.common.dro.quotation3.*;
import com.zmn.oms.common.dro.serviceitem.OrderServiceItemDRO;
import com.zmn.oms.common.dto.MapDTO;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.orderamount.OrderAmountCalcBO;
import com.zmn.oms.model.bo.orderamount.ReCalcOrderAmountDIO;
import com.zmn.oms.model.dto.part.SingleMasterOrderPartDTO;
import com.zmn.oms.model.dto.serviceitem.AddOrderServiceItemDTO;
import com.zmn.oms.model.dto.work.modify.ArtificialPromQueryDTO;
import com.zmn.oms.model.entity.acceptance.OrderWorkAcceptance;
import com.zmn.oms.model.entity.acceptance.OrderWorkAcceptanceDbQuery;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.order.OrderFinalPrice;
import com.zmn.oms.model.entity.orderfinalpricequotation.OrderFinalPriceQuotation;
import com.zmn.oms.model.entity.orderfinalpricequotation.OrderFinalPriceQuotationQuery;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.product.OrderProductExtend;
import com.zmn.oms.model.entity.quotation3.*;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItemCell;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.warranty.OrderWarranty;
import com.zmn.oms.model.entity.warranty.OrderWarrantyProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.persistence.interfaces.serviceitem.OrderServiceItemCellDao;
import com.zmn.oms.services.interfaces.acceptance.OrderWorkAcceptanceService;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.order.OrderFinalPriceService;
import com.zmn.oms.services.interfaces.orderfinalpricequotation.OrderFinalPriceQuotationService;
import com.zmn.oms.services.interfaces.product.OrderProductExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.quotation3.*;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyProductService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.quotation3.OrderQuotation3ListBService;
import com.zmn.oms.zmn.normal.business.interfaces.serviceitem.ZsNormalOrderServiceItemBService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.scm2.common.model.dro.scm.purchase.apply.ScmPurchaseApplyDRO;
import com.zmn.scm2.common.model.query.scm.purchase.apply.ScmPurchaseApplyQuery;
import com.zmn.scm2.dubbo.interfaces.scm.engineer.purchase.EngineerPurchaseListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.hbase.thirdparty.com.google.common.collect.Streams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author sunlife
 * @date:2021/12/2 6:43 下午
 * description:
 */
@Slf4j
@Service
public class OrderQuotation3ListBServiceImpl implements OrderQuotation3ListBService {

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderProductService orderProductService;
    @Autowired
    private OrderQuotationProcessService orderQuotationProcessService;
    @Autowired
    private OrderFaultPhenomenonService orderFaultPhenomenonService;
    @Autowired
    private OrderFaultService orderFaultService;
    @Autowired
    private OrderMaintainItemService orderMaintainItemService;
    @Autowired
    private OrderServiceContentService orderServiceContentService;
    @Autowired
    private OrderAmountBService orderAmountBService;
    @Autowired
    private OrderQuotation3ListBService orderQuotation3ListBService;
    @Autowired
    private OrderQuotationServiceItemService orderQuotationServiceItemService;
    @Autowired
    private OrderDiscountService orderDiscountService;
    @Autowired
    protected OrderVisitService orderVisitService;
    @Autowired
    private OrderWorkAcceptanceService orderWorkAcceptanceService;
    @Autowired
    private OrderServiceItemService orderServiceItemService;
    @Resource
    private OrderServiceItemCellDao orderServiceItemCellDao;
    @Autowired
    private OrderWarrantyService orderWarrantyService;
    @Autowired
    private OrderWarrantyProductService orderWarrantyProductService;
    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private OrderAmountCalcBService orderAmountCalcBService;
    @Autowired
    private OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    private OrderFinalPriceService orderFinalPriceService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private OrderPartBService orderPartBService;
    @Autowired
    private OrderProductExtendService orderProductExtendService;
    @Autowired
    private OrderQuotationServiceItemService orderquotationserviceitemService;
    @Autowired
    private ZsNormalOrderServiceItemBService zsNormalOrderServiceItemBService;
    @Autowired
    private OrderDiscountCalcBService orderDiscountCalcBService;

    @Resource
    private OrderFinalPriceQuotationService orderFinalPriceQuotationService;

    @Resource
    private OrderFinalPriceQuotationBService orderFinalPriceQuotationBService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private MeterFlow3RemoteService meterFlow3RemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CategRelationFaultImageListRemoteService categoryFaultImageRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CategServProductListRemoteService categServProductListRemoteService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private OrderAmountRemoteService orderAmountRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemWarrantyRemoteService itemWarrantyRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    protected ItemPriceRemoteService itemPriceRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemPartsRemoteService itemPartsRemoteService;
    @Reference(version = com.zmn.scm2.dubbo.interfaces.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerPurchaseListRemoteService engineerPurchaseListRemoteService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private FaultMaintainRelationListRemoteService faultMaintainRelationListRemoteService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private MaintainItemListRemoteService maintainItemListRemoteService;

    @DubboReference(version = com.zmn.coa.common.util.DubboConsts.INTERFACE_VERSION, check = false)
    protected OrderDiscountRemoteService orderDiscountRemoteService;

    @Override
    public UserConfirmedFaultInfoDRO getUserConfimedFaultInfo(Long orderId, Long workId) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
        }
        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderId);
        OrderProduct orderProduct = orderProducts.get(0);
        UserConfirmedFaultInfoDRO resultDRO = BeanMapper.map(orderWork, UserConfirmedFaultInfoDRO.class);
        BeanMapper.copy(orderProduct, resultDRO);

        // 计价器名称
        OrderFinalPriceQuotationDRO priceQuotationDRO = orderFinalPriceQuotationBService.getOrderFinalPriceQuotationByOrderIdAndWorkId(orderId, workId);
        if (Objects.nonNull(priceQuotationDRO)){
            resultDRO.setTariffName(priceQuotationDRO.getTariffName());
        }

        // 流程信息
        OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderId);
        if (Objects.isNull(process)) {
            return resultDRO;
        }

        // 已确认完善选择信息
        resultDRO.setIsConfirmFault(Objects.equals(process.getConfirmStatus(), GlobalConsts.YES) ? GlobalConsts.YES : GlobalConsts.NO);
        // 已选择的故障现象
        List<OrderFaultPhenomenon> phenList = orderFaultPhenomenonService.listByOrderId(orderId);
        if (CollectionUtil.isNullOrEmpty(phenList)) {
            if (Objects.nonNull(priceQuotationDRO)) {
                resultDRO.setFaultPhenList(Collections.singletonList(new FaultPhenoDRO(priceQuotationDRO.getPhenId(), priceQuotationDRO.getPhenName())));
            }
            return resultDRO;
        }

        resultDRO.setFaultPhenList(BeanMapper.mapList(phenList, FaultPhenoDRO.class));


//        List<Integer> phenIdList = phenList.stream().map(OrderFaultPhenomenon::getPhenId).collect(Collectors.toList());
        // 故障信息
        // 获取故障部位并存储 存储了故障现象对应的所有故障
//        MeterFaultQuery meterFaultQuery = MeterFaultQuery
//                .builder()
//                .erpProductId(orderWork.getProductId())
//                .bizType(orderWork.getBizType())
//                .channelId(orderWork.getChannelId())
//                .phenIdList(phenIdList)
//                .build();
//        ResponseDTO<List<com.zmn.base.common.data.common.dro.fault.FaultDRO>> faultResponseDTO = meterFlow3RemoteService.listFaultByQuery(meterFaultQuery);
//        if (!faultResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(faultResponseDTO.getData())) {
//            throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, faultResponseDTO.getMessage());
//        }
//        List<com.zmn.base.common.data.common.dro.fault.FaultDRO> faultDROList = faultResponseDTO.getData();
//        List<FaultDRO> faultList = BeanMapper.mapList(faultDROList, FaultDRO.class);
//        resultDRO.setFaultList(faultList);

        // 处理故障图片
        // 底图
//        ResponseDTO<com.zmn.base.product.common.dto.categ.FaultImageDRO> baseImageResponseDTO = categoryFaultImageRemoteService.getDefaultImageByServCategIdAndCategId(orderWork.getServCategId(), orderWork.getCategId());
//        if (!baseImageResponseDTO.isSuccess()) {
//            throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, baseImageResponseDTO.getMessage());
//        }
//        resultDRO.setFaultImage(baseImageResponseDTO.getData().getDefaultImg());
//
//        if (CollectionUtil.isNotNullOrEmpty(faultList)) {
//            List<Integer> faultIdList = faultList.stream().map(FaultDRO::getFaultId).collect(Collectors.toList());
//            ResponseDTO<List<com.zmn.base.product.common.dto.categ.FaultImageDRO>> imageResponseDTO = categoryFaultImageRemoteService.listFaultImageByServCategIdAndCategIdAndFaultIds(orderWork.getServCategId(), orderWork.getCategId(), faultIdList);
//            if (!imageResponseDTO.isSuccess()) {
//                throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, imageResponseDTO.getMessage());
//            }
//            List<com.zmn.base.product.common.dto.categ.FaultImageDRO> imageList = imageResponseDTO.getData();
//            if (CollectionUtil.isNotNullOrEmpty(imageList)) {
//                resultDRO.setFaultImageList(BeanMapper.mapList(imageList, com.zmn.oms.common.dro.quotation3.FaultImageDRO.class));
//            }
//        }

        //已存储的检修项目信息
//        List<OrderMaintainItem> maintainItemList = orderMaintainItemService.listByOrderId(orderId);
//        resultDRO.setMaintainItemList(BeanMapper.mapList(maintainItemList, OrderMaintainItemDRO.class));

        return resultDRO;
    }

    @Override
    public Integer getDiscount(CheckReportDIO checkReportDIO) throws OmsBaseException {
        if (StringUtils.isBlank(checkReportDIO.getOperator()) || NumberUtil.isNullOrZero(checkReportDIO.getOperatorType())) {
            throw new OmsBaseException(OmsErrorCodeConsts.PARAMS_OPERATOR_VERIFY_EXCEPTION, "操作人或操作人类型不能为空");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(checkReportDIO.getOrderId(), checkReportDIO.getWorkId());
        this.commonVerify(orderWork);

        OrderQuotationProcess dbProcess = orderQuotationProcessService.findByOrderId(checkReportDIO.getOrderId());
        if (Objects.isNull(dbProcess) || Objects.equals(dbProcess.getConfirmStatus(), GlobalConsts.NO)) {
            throw new OmsBaseException(OmsErrorCodeConsts.STATUS_NOT_LEGAL, "订单状态不合法，请重新操作计价流程");
        }

        // 校验配件
//        this.verifyPart(orderWork, checkReportDIO.getItemList());

        if (Objects.equals(dbProcess.getReportSubmitStatus(), GlobalConsts.YES)) {
            checkReportDIO.setEditStatus(GlobalConsts.YES);
        }

        // 生成价格
        Integer discount = this.generateOrderAmount(checkReportDIO, orderWork, checkReportDIO.getItemList());

        return discount;
    }

    @Override
    public CheckReportDRO getCheckReport(Long orderId, Long workId) throws OmsBaseException {
        if (NumberUtil.isNullOrZero(orderId) || NumberUtil.isNullOrZero(workId)) {
            throw new OmsBaseException("订单号或工单号不能为空");
        }
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
        }
        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderId);
        OrderProduct orderProduct = orderProducts.get(0);
        CheckReportDRO reportDRO = BeanMapper.map(orderWork, CheckReportDRO.class);
        BeanMapper.copy(orderProduct, reportDRO);
        reportDRO.setCheckReportStatus(GlobalConsts.NO); // 默认无检测报告

        // 流程信息
        OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderId);
        if (Objects.isNull(process)) {
            return reportDRO;
        }

        if (Objects.equals(process.getReportSubmitStatus(), GlobalConsts.YES)) {
            reportDRO.setCheckReportStatus(GlobalConsts.YES); // 默认无检测报告
        }

        // 已确认完善选择信息
        reportDRO.setIsConfirmFault(Objects.equals(process.getConfirmStatus(), GlobalConsts.YES) ? GlobalConsts.YES : GlobalConsts.NO);
        reportDRO.setIsAgree(process.getAgreeStatus());
        reportDRO.setIsConfirmReport(process.getReportConfirmStatus());
        reportDRO.setEditStatus(process.getEditStatus());
        reportDRO.setCheckType(process.getCheckType());
        reportDRO.setFaultCodeId(process.getFaultCodeId());
        reportDRO.setFaultCode(process.getFaultCode());
        // 已选择的故障现象
        List<OrderFaultPhenomenon> phenList = orderFaultPhenomenonService.listByOrderId(orderId);
        reportDRO.setFaultPhenList(BeanMapper.mapList(phenList, FaultPhenoDRO.class));

        if (CollectionUtil.isNotNullOrEmpty(phenList)) {
            Integer deteTime = phenList.stream().map(OrderFaultPhenomenon::getDeteTime).max(Integer::compareTo).get();
            Integer deteTimeSeconds = deteTime * 60;

            Date startChectTime = process.getStartCheckTime();
            if (Objects.nonNull(startChectTime)) {
                long mills = DateUtil.getNow().getTime() - startChectTime.getTime();
                long mins = mills / 1000 / 60;
                if (mins > deteTime) {
                    deteTime = 0;
                } else {
                    deteTime = deteTime - (int) mins;
                }

                long seconds = mills / 1000;
                if (seconds >= deteTimeSeconds) {
                    deteTimeSeconds = 0;
                } else {
                    deteTimeSeconds = deteTimeSeconds - (int) seconds;
                }
            }

            reportDRO.setDeteTime(deteTime);
            reportDRO.setDeteTimeSeconds(deteTimeSeconds);
        }

        // 故障信息
        List<OrderFault> orderFaultList = orderFaultService.listByOrderId(orderId);
        List<FaultDRO> faultList = BeanMapper.mapList(orderFaultList, FaultDRO.class);
        faultList.forEach(fault -> {
            fault.setFaultDifficultyName(OrderQuotation3Constant.getFaultDifficulty(fault.getFaultDifficulty()));
        });
        reportDRO.setFaultList(faultList);

        if (CollectionUtil.isNotNullOrEmpty(orderFaultList)) {
            Integer faultLevel = orderFaultList.stream().map(OrderFault::getFaultLevel).max(Integer::compareTo).get();
            reportDRO.setFaultLevel(faultLevel);
            reportDRO.setFaultLevelName(OrderQuotation3Constant.getFaultLevel(faultLevel));
        }

        // 处理 故障等级 字段
        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

            List<Integer> itemTypeIds;
            if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
                itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE);
            } else {
                itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
            }
            Optional<OrderServiceItem> maintainServiceItemOptional = orderServiceItemList.stream().filter(item ->
                    itemTypeIds.contains(item.getServItemGroupId())).findFirst();
            // 有维修项
            if (maintainServiceItemOptional.isPresent()) {
                reportDRO.setFaultLevelName(maintainServiceItemOptional.get().getServItemGroupName());
            } else {

                if (CollectionUtil.isNotNullOrEmpty(orderServiceItemList)) {
                    // 有上门费
                    Optional<OrderServiceItem> first = orderServiceItemList.stream()
                            .filter(e -> Objects.equals(e.getServItemGroupId(), ItemAdditionConst.ADDITION_DOOR_ID))
                            .findFirst();
                    if (first.isPresent()) {
                        reportDRO.setFaultLevelName("其他收费");
                    }
                } else {
                    List<OrderQuotationServiceItem> quotationServiceItemList = orderQuotationServiceItemService.listByOrderId(orderId);
                    if (CollectionUtil.isNotNullOrEmpty(quotationServiceItemList)) {
                        OrderQuotationServiceItem item = quotationServiceItemList.stream().max(Comparator.comparing(OrderQuotationServiceItem::getPrice)).get();
                        reportDRO.setFaultLevelName(item.getGroupName());
                    }
                }

            }

        }


        // 处理故障图片
        // 底图
//        ResponseDTO<com.zmn.base.product.common.dto.categ.FaultImageDRO> baseImageResponseDTO = categoryFaultImageRemoteService.getDefaultImageByServCategIdAndCategId(orderWork.getServCategId(), orderWork.getCategId());
//        if (!baseImageResponseDTO.isSuccess() || Objects.isNull(baseImageResponseDTO.getData())) {
//            throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, baseImageResponseDTO.getMessage());
//        }
        reportDRO.setFaultImage(process.getBaseImage());
        // 图片信息
        List<OrderFaultImage> orderFaultImages = Lists.newArrayList();
        // 图片链接set方便后期去重
        Set<String> imageSrcSet = Sets.newHashSet();
        orderFaultList.forEach(orderFault -> {
            if (StringUtils.isNotBlank(orderFault.getImgInfo())) {
                List<OrderFaultImage> images = JSON.parseArray(orderFault.getImgInfo(), OrderFaultImage.class);
                images.forEach(orderFaultImage -> {
                    if (imageSrcSet.add(orderFaultImage.getFaultImg())) {
                        orderFaultImages.add(orderFaultImage);
                    }
                });
            }
        });
        reportDRO.setFaultImageList(BeanMapper.mapList(orderFaultImages, FaultImageDRO.class));

        // 已存储的检修项目信息
        List<OrderMaintainItem> maintainItemList = orderMaintainItemService.listByOrderId(orderId);

        reportDRO.setMaintainItemIdList(maintainItemList.stream().map(OrderMaintainItem::getMaintainId).collect(Collectors.toList()));
        // 排序检修项目
        if (CollectionUtil.isNotNullOrEmpty(maintainItemList)) {
            List<OrderMaintainItem> items = Lists.newArrayList();
            items = maintainItemList.stream().filter(item -> Objects.nonNull(item.getResult())).sorted(Comparator.comparing(OrderMaintainItem::getResult)).collect(Collectors.toList());
            items.addAll(maintainItemList.stream().filter(item -> Objects.isNull(item.getResult())).collect(Collectors.toList()));
            maintainItemList = items;
        }

        reportDRO.setMaintainItemList(BeanMapper.mapList(maintainItemList, OrderMaintainItemDRO.class));

        // 检测项目数量、异常项目数量
        reportDRO.setMaintainItemCount(maintainItemList.size());
        Long abnormalMaintainItemCount = maintainItemList.stream().filter(item -> {
            return Objects.equals(item.getResult(), GlobalConsts.NO);
        }).count();
        reportDRO.setAbnormalMaintainItemCount(abnormalMaintainItemCount.intValue());

        // 已存储的服务内容
        List<OrderServiceContent> serviceContentList = orderServiceContentService.listByOrderId(orderId);
        if (CollectionUtil.isNotNullOrEmpty(serviceContentList)) {
            serviceContentList.sort(Comparator.comparing(OrderServiceContent::getServCharge).reversed());
        }
        reportDRO.setServiceContentList(BeanMapper.mapList(serviceContentList, ServiceContentDRO.class));

        // 价格信息
        reportDRO.setOrderAmount(orderQuotation3ListBService.getOrderAmount(orderId, workId, null));

        // 提交检测报告时选择的服务项目
        reportDRO.setQuotationOrderServiceItemIdList(this.quotationServiceItemIdList(orderWork));

        // 保修信息
        OrderWarrantyDRO warrantyDRO = new OrderWarrantyDRO();
        // 免责条款
        ResponseDTO<CategServProductGroupDRO> disclaimerResponse = categServProductListRemoteService.getBasisProductGroupByServCateIdAndCategId(orderWork.getServCategId(), orderWork.getCategId());
        if (!disclaimerResponse.isSuccess()) {
            throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, disclaimerResponse.getMessage());
        }
        warrantyDRO.setDisclaimer(disclaimerResponse.getData().getDisclaimer());

        OrderWarranty warranty = orderWarrantyService.findByOrderId(orderWork.getOrderId());
        List<OrderWarrantyProduct> warrantyProductList = orderWarrantyProductService.listByOrderId(orderWork.getOrderId());

        if (Objects.nonNull(warranty) && CollectionUtil.isNotNullOrEmpty(warrantyProductList)) {
            warrantyDRO.setEffectiveTime(Optional.ofNullable(warranty.getEffectiveTime()).orElse(DateUtil.getNow()));
            OrderWarrantyProduct warrantyProduct = warrantyProductList.get(0);

            List<MapDTO> mapList = JSON.parseArray(warrantyProduct.getFault(), MapDTO.class);
            warrantyDRO.setWarrantyContent(mapList.stream().map(MapDTO::getMapName).collect(Collectors.joining("，")));
            warrantyDRO.setEffectiveDays(warrantyProduct.getDay());
            warrantyDRO.setExpiredTime(Optional.ofNullable(warrantyProduct.getExpiredTime()).orElse(DateUtil.getNowDefer(warrantyDRO.getEffectiveDays())));
            reportDRO.setOrderWarrantyDRO(warrantyDRO);
        } else {
            log.info("订单[{}]获取保修信息 入参：{} {} {} {}", orderId, orderWork.getBizType(), orderWork.getProductId(), reportDRO.getQuotationOrderServiceItemIdList(), orderProduct.getTariffId());
            ResponseDTO<ItemWarrantyDetailDRO> warrantyInfoDROResponseDTO = itemWarrantyRemoteService.getByProductIdAndItemIdList(orderWork.getProductId(), reportDRO.getQuotationOrderServiceItemIdList());

            log.info("订单[{}]获取保修信息 出参：{}", orderId, JSON.toJSONString(warrantyInfoDROResponseDTO));
            if (warrantyInfoDROResponseDTO.isSuccess()) {
                if (Objects.nonNull(warrantyInfoDROResponseDTO.getData()) && !Objects.equals(warrantyInfoDROResponseDTO.getData().getWarrantyType(), WarrantyConst.RULE_NOWARRANTY)) {
                    ItemWarrantyDetailDRO warrantyInfo = warrantyInfoDROResponseDTO.getData();
                    warrantyDRO.setWarrantyContent(warrantyInfo.getContentOptionList().stream().map(Option::getLabel).collect(Collectors.joining("，")));
                    warrantyDRO.setEffectiveDays(warrantyInfo.getDays().stream().mapToInt(Integer::valueOf).max().getAsInt());
                    warrantyDRO.setEffectiveTime(DateUtil.getNow());
                    warrantyDRO.setExpiredTime(DateUtil.getNowDefer(warrantyDRO.getEffectiveDays()));

                    reportDRO.setOrderWarrantyDRO(warrantyDRO);
                }
            }
        }

        // 金额List
        reportDRO.setAmountList(this.amountListSet(orderWork));

        // 附加项
        reportDRO.setOrderServiceItemList(this.serviceItemListSet(orderWork));

        // 待支付金额
        reportDRO.setWaitPayAmount(this.waitPayAmountSet(orderWork));
        //支付优惠的金额
        reportDRO.setPayDiscountAmount(orderWork.getPayDiscountAmount());

        // 一口价订单处理
        if (Objects.equals(orderWork.getFinalPrice(),GlobalConsts.YES) ||
                Objects.equals(orderWork.getServItemType(),OrderConsts.SERVICE_ITEM_TYPE_ORDER)){
            // 后台二级分类
            reportDRO.setCategId(orderProduct.getCategId());
            reportDRO.setCategName(orderProduct.getCategName());


            List<OrderFinalPriceQuotation> orderFinalPriceQuotations = orderFinalPriceQuotationService.
                    listByQuery(OrderFinalPriceQuotationQuery.builder().orderId(orderId).workId(workId).build());
            if (CollectionUtil.isNotNullOrEmpty(orderFinalPriceQuotations)){
                OrderFinalPriceQuotation orderFinalPriceQuotation = orderFinalPriceQuotations.get(0);
                // 故障现象
                if (CollectionUtil.isNotNullOrEmpty(phenList)){
                    OrderFaultPhenomenon orderFaultPhenomenon = phenList.get(0);
                    reportDRO.setPhenId(orderFaultPhenomenon.getPhenId());
                    reportDRO.setPhenName(orderFaultPhenomenon.getPhenName());
                    if (!Objects.equals(orderFinalPriceQuotation.getPhenId(),orderFaultPhenomenon.getPhenId())){
                        List<OrderServiceItem> orderServiceItems = orderServiceItemService.listByOrderId(orderId);
                        if (CollectionUtil.isNotNullOrEmpty(orderServiceItems)){
                            reportDRO.setPhenChargePromptStr("服务项目变更，需要" + orderServiceItems.get(0).getServItemName() +
                                    "，属于" + orderFaultPhenomenon.getPhenName());
                        }
                        reportDRO.setOldPhenId(orderFinalPriceQuotation.getPhenId());
                        reportDRO.setOldPhenName(orderFinalPriceQuotation.getPhenName());
                    }
                }
                // 计价器名称
                reportDRO.setTariffName(orderFinalPriceQuotation.getTariffName());
                if (!Objects.equals(orderProduct.getCategId(),orderFinalPriceQuotation.getCategId())){
                    reportDRO.setOldCategId(orderFinalPriceQuotation.getCategId());
                    reportDRO.setOldCategName(orderFinalPriceQuotation.getCategName());
                }
                // 品牌
                if (!Objects.equals(orderProduct.getBrandId(),orderFinalPriceQuotation.getBrandId())){
                    reportDRO.setOldBrandId(orderFinalPriceQuotation.getBrandId());
                    reportDRO.setOldBrandName(orderFinalPriceQuotation.getBrandName());
                }
                // 产品
                if (!Objects.equals(orderProduct.getProductId(),orderFinalPriceQuotation.getProductId())){
                    reportDRO.setOldShowProductId(orderFinalPriceQuotation.getShowProductId());
                    reportDRO.setOldShowProductName(orderFinalPriceQuotation.getShowProductName());
                    reportDRO.setOldTariffName(orderFinalPriceQuotation.getOldTariffName());
                }
                // 价格
                OrderAmountDRO orderAmount = reportDRO.getOrderAmount();
                if (Objects.nonNull(orderAmount) && !Objects.equals(orderFinalPriceQuotation.getItemPrice(),orderAmount.getServItemPrice())){
                    orderAmount.setOldServItemPrice(orderFinalPriceQuotation.getItemPrice());
                }
                reportDRO.setOrderAmount(orderAmount);
            }
        }
        return reportDRO;
    }

    private void setServChargePromptStr(OrderWork orderWork, OrderAmountDRO orderAmount, OrderQuotationProcess process, List<OrderServiceItem> orderServiceItemList) throws OmsBaseException {
        if (!Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            return;
        }

        if (Objects.isNull(orderAmount)) {
            return;
        }

        if (Objects.isNull(orderAmount.getTotalFee())) {
            return;
        }

        String servChargePromptStr = null;

        if (Objects.equals(orderAmount.getTotalFee(), GlobalConsts.NONE)) {
            servChargePromptStr = "如工程师私下加收其他费用，可拒绝付款！";
            orderAmount.setServChargePromptStr(servChargePromptStr);
            return;
        }

        List<Integer> itemTypeIds;
        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE);
        } else {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
        }
        Optional<OrderServiceItem> maintainServiceItemOptional = orderServiceItemList.stream().filter(item ->
                itemTypeIds.contains(item.getServItemGroupId())).findFirst();

        String itemTypeName = null;
        if (maintainServiceItemOptional.isPresent() && !Objects.equals(process.getAgreeStatus(), GlobalConsts.NO)) {
            OrderServiceItem serviceItem = maintainServiceItemOptional.get();
            itemTypeName = serviceItem.getServItemGroupName();
        } else {
            List<OrderQuotationServiceItem> serviceItemList = orderQuotationServiceItemService.listByOrderId(orderWork.getOrderId());
            if (CollectionUtil.isNullOrEmpty(serviceItemList)) {
                return;
            }
            List<Integer> serviceItemIdList = serviceItemList.stream()
                    .map(OrderQuotationServiceItem::getItemId)
                    .collect(Collectors.toList());
            List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
            OrderProduct orderProduct = orderProducts.get(0);
            // 处理服务项
            ItemQuoteQuery quoteQuery3 = ItemQuoteQuery.builder()
                    .bizType(orderWork.getBizType())
                    .channelId(orderWork.getChannelId())
                    .cityId(orderWork.getCityId())
                    .productId(orderWork.getProductId())
                    .brandId(orderProduct.getBrandId())
                    .tariffId(orderProduct.getTariffId())
                    .itemList(serviceItemIdList).build();
            ResponseDTO<List<ItemDRO>> itemResponseDTO = itemPriceRemoteService.listItemQuoteByQuery(quoteQuery3);
            log.info("计价器工单确认检测报告获取服务项：入参：{} 出参：{}", JSON.toJSONString(quoteQuery3), JSON.toJSONString(itemResponseDTO));
            if (!itemResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(itemResponseDTO.getData())) {
                throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, itemResponseDTO.getMessage());
            }
            List<ItemDRO> itemDRO3List = itemResponseDTO.getData();
            ItemDRO item = itemDRO3List.stream().max(Comparator.comparing(ItemDRO::getPrice)).get();
            itemTypeName = item.getItemTypeName();
        }

        if (orderAmount.getTotalFee() > 0) {
            servChargePromptStr = String.format("检测结果为%s，服务完成后需补足差价", itemTypeName);
        } else {
            servChargePromptStr = String.format("检测结果为%s，服务完成后自动退款", itemTypeName);
        }
        orderAmount.setServChargePromptStr(servChargePromptStr);
    }

    /**
     * 待支付
     *
     * @param orderWork
     * @return
     */
    private Integer waitPayAmountSet(OrderWork orderWork) {
        Integer waitPayAmount = null;
        // 取消状态
        List<Integer> resultStatusList = Lists.newArrayList(OrderStatusConsts.WORK_RESULT_FAIL, OrderStatusConsts.WORK_RESULT_DISCARD);
        // 未取消/失败
        boolean resultStatusSupport = !resultStatusList.contains(orderWork.getResultStatus());
        // 未完成
        boolean isComplete = orderWork.getCompleteTime() == null;
        // 未取消 未完成 待支付
        if (Objects.equals(PayConsts.PAY_STATUS_ING, orderWork.getPrepayStatus()) && resultStatusSupport && isComplete) {
            waitPayAmount = orderWork.getPrepayAmount();
            return waitPayAmount;
        }

        // 定金未支付
        if (!NumberUtil.isNullOrZero(orderWork.getDepositAmount()) && Objects.equals(orderWork.getDepositStatus(), PayConsts.PAY_STATUS_NONE) && orderWork.getDepositTime() == null) {
            waitPayAmount = Optional.ofNullable(waitPayAmount).orElse(0) + orderWork.getDepositAmount();
        }
        // 师傅收款额度
        if (!Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE) && !NumberUtil.isNullOrZero(orderWork.getMasterAmount())) {
            waitPayAmount = Optional.ofNullable(waitPayAmount).orElse(0) + orderWork.getMasterAmount();
        }
        return waitPayAmount;
    }

    /**
     * 附加项
     *
     * @param orderWork
     * @return
     */
    private List<Integer> quotationServiceItemIdList(OrderWork orderWork) {
        List<OrderQuotationServiceItem> serviceItemList = orderQuotationServiceItemService.listByOrderId(orderWork.getOrderId());
        if (CollectionUtil.isNullOrEmpty(serviceItemList)) {
            return Lists.newArrayList();
        }
        return serviceItemList.stream().map(OrderQuotationServiceItem::getItemId)
                .collect(Collectors.toList());
    }

    /**
     * 附加项
     *
     * @param orderWork
     * @return
     */
    private List<OrderServiceItemDRO> serviceItemListSet(OrderWork orderWork) {
        List<OrderServiceItem> serviceItemList = orderServiceItemService.listByOrderId(orderWork.getOrderId());
        if (CollectionUtil.isNullOrEmpty(serviceItemList)) {
            return null;
        }
        // 附加项类型id集合
        List<Integer> additionalServiceTypeIdList = new ArrayList<>();
        if (Objects.equals(orderWork.getFinalPrice(), com.zmn.consts.GlobalConsts.YES)) {
            additionalServiceTypeIdList.add(ItemTypeConst.EXTRA_ITEM);
        } else {
            additionalServiceTypeIdList.add(ItemTypeConst.ADDITION_ITEM);
        }

        serviceItemList = serviceItemList.stream()
                .filter(e -> additionalServiceTypeIdList.contains(e.getServItemGroupId()))
                .collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(serviceItemList)) {
            return null;
        }
        List<OrderServiceItemDRO> list = Lists.newArrayListWithCapacity(serviceItemList.size());
        serviceItemList.forEach(item -> {
            OrderServiceItemDRO dro = new OrderServiceItemDRO();
            dro.setProExtId(item.getProExtId());
            dro.setServItemId(item.getServItemId());
            dro.setServItemName(item.getServItemName());
            dro.setServItemCategId(item.getServItemCategId());
            dro.setItemPrice(item.getItemPrice());
            dro.setNumber(item.getNumber());
            dro.setTotalPrice(item.getTotalPrice());
            list.add(dro);
        });
        return list;
    }

    // 处理金额
    private List<AmountDRO> amountListSet(OrderWork orderWork) {
        // 查询上门记录
        List<OrderVisit> orderVisitList = orderVisitService.listByOrderIdSrcMaster(orderWork.getOrderId());
        if (CollectionUtil.isNullOrEmpty(orderVisitList)) {
            OrderWorkAcceptanceDbQuery query = new OrderWorkAcceptanceDbQuery();
            query.setOrderId(orderWork.getOrderId());
            List<OrderWorkAcceptance> acceptanceList = orderWorkAcceptanceService.listOrderWorkAcceptanceByQuerySrcMaster(query);
            if (CollectionUtil.isNotNullOrEmpty(acceptanceList)) {
                // 兼容性处理
                List<AmountDRO> amountDROList = Lists.newArrayListWithCapacity(2);
                OrderWorkAcceptance deposit = acceptanceList.stream()
                        .filter(item -> Objects.equals(item.getAcceptanceType(), OrderConsts.ORDER_ACCEPTANCE_TYPE_DEPOSIT))
                        .findFirst().orElse(null);
                if (Objects.nonNull(deposit)) {
                    AmountDRO dro = new AmountDRO();
                    dro.setAcceptanceId(deposit.getAcceptanceId());
                    dro.setAmount(Optional.ofNullable(orderWork.getDepositAmount()).orElse(0));
                    dro.setAmountType(OrderPayConsts.ORDER_PAY_DEPOSIT);
                    dro.setPayStatus(orderWork.getDepositStatus());
                    amountDROList.add(dro);
                }

                OrderWorkAcceptance payment = acceptanceList.stream()
                        .filter(item -> Objects.equals(item.getAcceptanceType(), OrderConsts.ORDER_ACCEPTANCE_TYPE_PAYMENT))
                        .findFirst().orElse(null);
                if (Objects.nonNull(payment)) {
                    AmountDRO dro = new AmountDRO();
                    dro.setAcceptanceId(payment.getAcceptanceId());
                    dro.setAmount(Optional.ofNullable(orderWork.getMasterAmount()).orElse(0));
                    dro.setAmountType(OrderPayConsts.ORDER_PAY_MASTER);
                    dro.setPayStatus(orderWork.getMasterPayStatus());
                    amountDROList.add(dro);
                }
                return amountDROList;
            }
        }

        List<AmountDRO> amountDROList = Lists.newArrayListWithCapacity(orderVisitList.size());

        orderVisitList.forEach(orderVisit -> {
            // 过滤已取消的上门
            if (Objects.equals(orderVisit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)) {
                if (Objects.equals(orderVisit.getPayStatus(), PayConsts.PAY_STATUS_NONE)) {
                    return;
                }
            }

            AmountDRO dro = new AmountDRO();
            dro.setAcceptanceId(orderVisit.getAcceptanceId());
            dro.setVisitId(orderVisit.getVisitId());
            dro.setOrderPayId(orderVisit.getOrderPayId());
            dro.setAmount(orderVisit.getAmount());
            dro.setAmountType(orderVisit.getAmountType());
            if (NumberUtil.isNullOrZero(orderVisit.getOrderPayId()) && NumberUtil.isNullOrZero(orderVisit.getAcceptanceId())) {
                dro.setPayStatus(PayConsts.PAY_STATUS_DONE);
            } else {
                dro.setPayStatus(orderVisit.getPayStatus());
            }
            amountDROList.add(dro);
        });

        OrderWorkAcceptanceDbQuery query = new OrderWorkAcceptanceDbQuery();
        query.setOrderId(orderWork.getOrderId());
        List<OrderWorkAcceptance> acceptanceList = orderWorkAcceptanceService.listOrderWorkAcceptanceByQuerySrcMaster(query);
        if (CollectionUtil.isNotNullOrEmpty(acceptanceList)) {
            OrderWorkAcceptance acceptance = Streams.findLast(acceptanceList.stream()
                            .filter(item -> Objects.equals(item.getAcceptanceType(), OrderConsts.ORDER_ACCEPTANCE_TYPE_PAYMENT)))
                    .orElse(null);
            if (Objects.nonNull(acceptance)) {
                AmountDRO waitAmountDRO = Streams.findLast(amountDROList.stream()
                                .filter(item -> Objects.equals(item.getPayStatus(), PayConsts.PAY_STATUS_NONE)))
                        .orElse(null);
                int waitAmount = 0;
                if (Objects.nonNull(waitAmountDRO)) {
                    waitAmount = waitAmountDRO.getAmount();
                }
                AmountDRO dro = new AmountDRO();
                dro.setAcceptanceId(acceptance.getAcceptanceId());
                dro.setAmount(Optional.ofNullable(orderWork.getMasterAmount()).orElse(0) - waitAmount);
                dro.setAmountType(OrderPayConsts.ORDER_PAY_MASTER);
                dro.setPayStatus(orderWork.getMasterPayStatus());
                amountDROList.add(dro);
            }
        }
        return amountDROList;
    }

    @Override
    public OrderAmountDRO refreshOrderAmount(Long orderId, Long workId, Integer engineerDiscountId) throws OmsBaseException {
        // 刷新优惠
        log.info("工程师获取最新优惠入参：{}, {}, {}", orderId, workId, engineerDiscountId);
        String lockKey = String.format("%s", orderId);
        DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

        try {
            if (lock.tryLock()) {
                boolean canRefreshDiscount = true;

                OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
                if (Objects.isNull(orderWork)) {
                    throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
                }
                if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                        || orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
                    canRefreshDiscount = false;
                }
                if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE)) {
                    canRefreshDiscount = false;
                }
                // 如果有工程师优惠ID，仅计算价格，不刷新优惠
                if (NumberUtil.isNotNullOrZero(engineerDiscountId)) {
                    canRefreshDiscount = false;
                }

                if (canRefreshDiscount) {

                    ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);

                    OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.REFRESH_DISCOUNT, calcOrderAmountDIO, null);
                    //主从并发问题，发现订单已完成
                    if (NumberUtil.isNotNullOrZero(orderWork.getChannelPrepayAmount()) || NumberUtil.isNotNullOrZero(orderAmountCalcBO.getChannelPrepayAmount())) {
                        OrderWork orderWorkByKeySrcMaster = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
                        if (!Objects.equals(orderWorkByKeySrcMaster.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                                || orderWorkByKeySrcMaster.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
                            log.info("[{}}工程师获取最新优惠---查主库订单已完成，不处理", workId);
                        }
                    }
                    orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);
                }
            }
        } catch (OmsBaseException e) {
            log.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new OmsBaseException("重新获取优惠异常");
        } finally {
            lock.unlock();
        }

        // 获取价格
        OrderAmountDRO orderAmount = this.getOrderAmount(orderId, workId, engineerDiscountId);

        return orderAmount;
    }

    @Override
    public OrderAmountDRO refreshOrderAmount2(Long orderId, Long workId, Integer discountAmount) throws OmsBaseException {
        // 刷新优惠
        log.info("工程师获取最新优惠入参：{}, {}, {}", orderId, workId, discountAmount);
        String lockKey = String.format("%s", orderId);
        DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

        try {
            if (lock.tryLock()) {
                boolean canRefreshDiscount = true;

                OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
                if (Objects.isNull(orderWork)) {
                    throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
                }
                if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                        || orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
                    canRefreshDiscount = false;
                }
                if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE)) {
                    canRefreshDiscount = false;
                }
                // 如果有工程师优惠金额，仅计算价格，不刷新优惠
                if (NumberUtil.isNotNullOrZero(discountAmount)) {
                    canRefreshDiscount = false;
                }

                if (canRefreshDiscount) {

                    ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);

                    OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.REFRESH_DISCOUNT, calcOrderAmountDIO, null);
                    //主从并发问题，发现订单已完成
                    if (NumberUtil.isNotNullOrZero(orderWork.getChannelPrepayAmount()) || NumberUtil.isNotNullOrZero(orderAmountCalcBO.getChannelPrepayAmount())) {
                        OrderWork orderWorkByKeySrcMaster = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
                        if (!Objects.equals(orderWorkByKeySrcMaster.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                                || orderWorkByKeySrcMaster.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
                            log.info("[{}}工程师获取最新优惠---查主库订单已完成，不处理", workId);
                        }
                    }
                    orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);
                }
            }
        } catch (OmsBaseException e) {
            log.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new OmsBaseException("重新获取优惠异常");
        } finally {
            lock.unlock();
        }

        // 获取价格
        OrderAmountDRO orderAmount = this.getOrderAmount2(orderId, workId, discountAmount);
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
        // 获取工单详情页剩余应收金额
        Integer masterAmount = orderWork.getMasterAmount();
        List<OrderDiscount> discounts = orderDiscountService.listByOrderIdSrcMaster(orderId);
        // 获取人工优惠金额
        Integer artificialDiscountAmount = discounts.stream().filter(discount -> Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL)).mapToInt(OrderDiscount::getAmount).sum();
        // 应收=订单总金额-优惠金额（全部） | 应收+人工优惠金额
        orderAmount.setMasterAmount(masterAmount + artificialDiscountAmount);
        return orderAmount;
    }

    @Override
    public OrderAmountDRO getOrderAmount(Long orderId, Long workId, Integer engineerDiscountId) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
        }

        OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderId);

        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

        List<Integer> itemTypeIds;
        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE);
        } else {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
        }
        Optional<OrderServiceItem> maintainServiceItemOptional = orderServiceItemList.stream().filter(item ->
                itemTypeIds.contains(item.getServItemGroupId())).findFirst();
        OrderAmountDRO orderAmountDRO = new OrderAmountDRO();
        if (maintainServiceItemOptional.isPresent() && !Objects.equals(process.getAgreeStatus(), GlobalConsts.NO)) {
            // 已有价格
            OrderServiceItem serviceItem = maintainServiceItemOptional.get();
            List<OrderServiceItemCell> orderServiceItemDetails = orderServiceItemCellDao.listByOrderIdAndServItemId(orderId, workId, serviceItem.getServItemId());
            // 增值服务项价格
            List<Integer> additionalServiceTypeIdList = new ArrayList<>();
            if (Objects.equals(orderWork.getFinalPrice(), com.zmn.consts.GlobalConsts.YES)) {
                additionalServiceTypeIdList.add(ItemTypeConst.EXTRA_ITEM);
            } else {
                additionalServiceTypeIdList.add(ItemTypeConst.ADDITION_ITEM);
            }
            Integer additionalItemAmount = orderServiceItemList.stream().filter(item -> additionalServiceTypeIdList.contains(item.getServItemGroupId())).mapToInt(OrderServiceItem::getTotalPrice).sum();

            if (CollectionUtil.isNotNullOrEmpty(orderServiceItemDetails)) {
                List<OrderAmountDetailDRO> detailDROS = new ArrayList<>(orderServiceItemDetails.size());
                for (OrderServiceItemCell orderServiceItemDetail : orderServiceItemDetails) {
                    OrderAmountDetailDRO detailDRO = new OrderAmountDetailDRO();
                    detailDRO.setItemCellId(orderServiceItemDetail.getItemCellId());
                    detailDRO.setItemCellName(orderServiceItemDetail.getItemCellName());
                    detailDRO.setCellPrice(orderServiceItemDetail.getCellPrice());
                    detailDROS.add(detailDRO);
                    // 兼容老包
                    switch (orderServiceItemDetail.getItemCellId()) {
                        case ItemCellConst.ITEM_CELL_PART:
                            orderAmountDRO.setPartPrice(orderServiceItemDetail.getCellPrice());
                            break;
                        case ItemCellConst.ITEM_CELL_HOUR:
                            orderAmountDRO.setHourFee(orderServiceItemDetail.getCellPrice());
                            break;
                        case ItemCellConst.ITEM_CELL_TRIP:
                            orderAmountDRO.setTrafficFee(orderServiceItemDetail.getCellPrice());
                            break;
                    }
                }
                orderAmountDRO.setDetailList(detailDROS);
            }
            Integer payDiscountAmount = orderWork.getPayDiscountAmount();

            // 处理已付金额
            Integer factAmount = orderAmountBService.getOrderWorkFactAmount(orderWork);

            List<OrderDiscount> discounts = orderDiscountService.listByOrderIdSrcMaster(orderId);
            if (NumberUtil.isNotNullOrZero(engineerDiscountId)) {
                if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
                    ArtificialPromDIO dio = ArtificialPromDIO.builder()
                            .tariffType(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE)
                            .orderId(orderWork.getOrderId())
                            .channelId(orderWork.getChannelId())
                            .cityId(orderWork.getCityId())
                            .productId(orderWork.getShowProductId())
                            .promId(engineerDiscountId)
                            .orderAmount(orderWork.getOriginalAmount())
                            .paidPrice(factAmount)
                            .usedDiscountAmount(orderWork.getDiscountAmount())
                            .build();
                    log.info("[{}]计价器3.0调用优惠计算接口：入参：{}", orderId, dio);
                    ResponseDTO<Integer> amountResponse = orderAmountRemoteService.getDiscount(dio);
                    log.info("[{}]计价器3.0调用优惠计算接口：出参：{}", orderId, amountResponse);
                    if (!amountResponse.isSuccess()) {
                        throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, "计算优惠失败");
                    }
                    orderAmountDRO.setTotalFee(amountResponse.getData());
                    orderAmountDRO.setRemainingReceivableAmount(amountResponse.getData() - factAmount);
                    return orderAmountDRO;
                } else {
                    // 此时工程师操作请求优惠，需要根据人工优惠ID实时计算
                    Integer useDlaborPreferenceAmount = discounts.stream().filter(discount -> Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL)).mapToInt(OrderDiscount::getAmount).sum();
                    Integer beforeLaborPreferenceAmount = orderWork.getTotalAmount() + useDlaborPreferenceAmount;

                    ArtificialPromDIO dio = ArtificialPromDIO.builder()
                            .tariffType(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)
                            .channelId(orderWork.getChannelId())
                            .cityId(orderWork.getCityId())
                            .productId(orderWork.getShowProductId())
                            .promId(engineerDiscountId)
                            .orderAmount(beforeLaborPreferenceAmount)
                            .paidPrice(factAmount)
                            .build();
                    log.info("[{}]计价器3.0调用优惠计算接口：入参：{}", orderId, dio);
                    ResponseDTO<Integer> amountResponse = orderAmountRemoteService.getDiscount(dio);
                    log.info("[{}]计价器3.0调用优惠计算接口：出参：{}", orderId, amountResponse);
                    if (!amountResponse.isSuccess()) {
                        throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, "计算优惠失败");
                    }
                    orderAmountDRO.setTotalFee(amountResponse.getData());
                    orderAmountDRO.setRemainingReceivableAmount(amountResponse.getData() - factAmount);
                    return orderAmountDRO;
                }
            }
            if (CollectionUtil.isNotNullOrEmpty(discounts)) {
                Integer coupDiscountAmount = discounts.stream().filter(discount -> Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON) || Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_CASH_COUPON)).mapToInt(OrderDiscount::getAmount).sum();
                Integer otherDiscountAmount = discounts.stream().filter(discount -> !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON) && !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_CASH_COUPON)).mapToInt(OrderDiscount::getAmount).sum();

                orderAmountDRO.setCoupDiscountAmount(coupDiscountAmount);
                orderAmountDRO.setOtherDiscountAmount(otherDiscountAmount);
            }
            orderAmountDRO.setDepositAmount(factAmount);
            orderAmountDRO.setTotalFee(orderWork.getTotalAmount() - factAmount - additionalItemAmount);
            orderAmountDRO.setRemainingReceivableAmount(orderWork.getTotalAmount() - factAmount);
            orderAmountDRO.setServItemPrice(serviceItem.getTotalPrice());
            orderAmountDRO.setServItemName(serviceItem.getServItemName());
            orderAmountDRO.setPayDiscountAmount(payDiscountAmount);
        } else {
            // 没有价格
            orderAmountDRO = orderAmountBService.getQuotationOrderAmountByOrderIdAndWorkId(orderId, workId, null);
        }

        // 一口价下单参数
        this.setfinalPriceOrderExtDRO(orderWork, orderAmountDRO);
        this.setServChargePromptStr(orderWork, orderAmountDRO, process, orderServiceItemList);

        return orderAmountDRO;
    }

    private void setfinalPriceOrderExtDRO(OrderWork orderWork, OrderAmountDRO orderAmountDRO) {
        if (!Objects.equals(orderWork.getFinalPrice(), com.zmn.consts.GlobalConsts.YES)) {
            return;
        }

        OrderFinalPrice ext = orderFinalPriceService.findByOrderIdAndWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        if (Objects.isNull(ext)) {
            return;
        }

        if (Objects.isNull(orderAmountDRO)) {
            return;
        }

        orderAmountDRO.setPaceanOrderPayType(ext.getPayType());
        orderAmountDRO.setPaceanOrderItemTypeName(ext.getItemTypeName());
    }

    @Override
    public List<ArtificialPromDRO> listArtificialProm(ArtificialPromListQuery query) throws OmsBaseException {
        log.info("获取人工优惠信息列表#listArtificialProm query={}", query);

        ArtificialPromQueryDTO queryDTO = new ArtificialPromQueryDTO();
        queryDTO.setOrderExtendedWarranty(query.getOrderExtendedWarranty());
        queryDTO.setBizType(query.getBizType());
        queryDTO.setChannelId(query.getChannelId());
        queryDTO.setCityId(query.getCityId());
        queryDTO.setPlat(query.getPlat());
        queryDTO.setProductId(query.getProductId());

        // 判断服务订单类型
        Long orderId = query.getOrderId();
        Long workId = query.getWorkId();
        Integer servItemType = OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE;
        if (Objects.nonNull(orderId) && Objects.nonNull(workId)) {
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
            // 没有尾款 不申请优惠
            if (NumberUtil.isNullOrZero(orderWork.getMasterAmount()) || orderWork.getMasterAmount() < 0) {
                return Collections.EMPTY_LIST;
            }

            if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
                servItemType = OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE;

                queryDTO.setOrderId(orderId);
                queryDTO.setWorkId(workId);
                queryDTO.setPartUse(orderWork.getPartUse());
                queryDTO.setOriginalAmount(orderWork.getOriginalAmount());
                queryDTO.setUsedDiscountAmount(orderWork.getDiscountAmount());
            }
        }

        return servItemBService.listArtificialProm(servItemType, queryDTO);
    }


    @Override
    public List<MaintainOptionDRO> listMaintainOptionByMfoQuery(MaintainFaultOptionQuery maintainFaultOptionQuery) throws OmsBaseException {

        List<Integer> faultIds = maintainFaultOptionQuery.getFaultIds();
        List<MaintainOptionQuery> maintainOptions = maintainFaultOptionQuery.getMaintainOptions();
        List<Integer> maintainIds = maintainOptions.stream().map(MaintainOptionQuery::getMaintainId).distinct().collect(Collectors.toList());
        ResponseDTO<List<FaultMaintainRelationDRO>> listResponseDTO = faultMaintainRelationListRemoteService.listById(faultIds, maintainIds);
        if (!listResponseDTO.isSuccess()) {
            log.error("faultMaintainRelationListRemoteService.listById调用失败，{}", listResponseDTO);
            throw new OmsBaseException("faultMaintainRelationListRemoteService.listById调用失败");
        }
        List<FaultMaintainRelationDRO> maintainRelations = listResponseDTO.getData();
        if (CollectionUtil.isNullOrEmpty(maintainRelations)) {
            log.info("faultMaintainRelationListRemoteService.listById返回为空");
            return null;
        }

        // 有关联关系的检测项目
        List<Integer> maintainRelationIds = maintainRelations.stream().map(FaultMaintainRelationDRO::getMaintainId).collect(Collectors.toList());
        ResponseDTO<List<MaintainItemDRO>> listResponseDTO1 = maintainItemListRemoteService.listMaintainOptionByMaintainIds(maintainRelationIds);
        if (!listResponseDTO1.isSuccess()) {
            log.error("maintainItemListRemoteService.listMaintainOptionByMaintainIds，{}", listResponseDTO);
            throw new OmsBaseException("maintainItemListRemoteService.listMaintainOptionByMaintainIds调用失败");
        }
        List<MaintainItemDRO> maintainItems = listResponseDTO1.getData();

        return maintainItems.stream().map(maintainItemDRO -> {
            MaintainOptionDRO maintainOptionDRO = new MaintainOptionDRO();
            maintainOptionDRO.setMaintainId(maintainItemDRO.getMaintainId());
            List<OptionRelationDRO> optionRelations = maintainItemDRO.getOptionRelations();
            List<OptionRelationDRO> optionRelationDROList = optionRelations.stream().filter(optionRelationDRO ->
                    Objects.equals(optionRelationDRO.getNormal(), PlatEngineConsts.NO)).collect(Collectors.toList());
            maintainOptionDRO.setOptionId(optionRelationDROList.get(0).getOptionId());
            return maintainOptionDRO;
        }).collect(Collectors.toList());
    }

    @Override
    public Integer processArtificial(Long orderId,Long workId,Integer discountAmount) throws OmsBaseException {
        log.info("处理优惠#processArtificial orderId={},workId={},discountAmount={}", orderId,workId,discountAmount);
        // 判断服务订单类型
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        // 没有尾款 不申请优惠
        if (NumberUtil.isNullOrZero(orderWork.getMasterAmount()) || orderWork.getMasterAmount() < 0) {
            return 0;
        }

        List<OrderDiscount> discounts = orderDiscountService.listByOrderIdSrcMaster(orderId);
        Integer otherDiscountAmount = 0;
        if (CollectionUtil.isNotNullOrEmpty(discounts)){
            otherDiscountAmount = discounts.stream().filter(discount -> !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON) && !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_CASH_COUPON)).mapToInt(OrderDiscount::getAmount).sum();
            log.info("处理优惠，其他优惠={}",otherDiscountAmount);
        }

        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            // 一口价订单
            if (Objects.equals(orderWork.getPartUse(),GlobalConsts.YES)){
                // 如果使用了配件
                log.info("获取订单最高优惠#getOrderMaxDiscount orderAmount={},orderId={}", orderWork.getOriginalAmount(), orderId);
                ResponseDTO<Integer> orderMaxDiscount = orderDiscountRemoteService.getOrderMaxDiscount(orderWork.getOriginalAmount(), orderId);
                log.info("获取订单最高优惠#getOrderMaxDiscount orderMaxDiscount={}", orderMaxDiscount);
                if (!orderMaxDiscount.isSuccess() || Objects.isNull(orderMaxDiscount.getData())){
                    throw new OmsBaseException("获取订单最高优惠出错");
                }
                Integer masterAmount = orderWork.getMasterAmount();
                // 获取最大优惠
                ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);
                calcOrderAmountDIO.setNewArtificialDiscountAmount(discountAmount);
                Integer artificialMaxDiscount = orderDiscountCalcBService.getArtificialMaxDiscount(TriggerAmountChangeEnum.ARTIFICIAL_MASTER_DISCOUNT, calcOrderAmountDIO);
                log.info("#processArtificial#最大优惠金额 出参：{}",artificialMaxDiscount);
                if (orderMaxDiscount.getData() > artificialMaxDiscount){
                    return artificialMaxDiscount;
                }
                return orderMaxDiscount.getData();
            } else {
                // 如果优惠金额大于剩余应收金额
                Integer masterAmount = orderWork.getMasterAmount();
                if (masterAmount+otherDiscountAmount < discountAmount){
                    return masterAmount+otherDiscountAmount;
                }
                return discountAmount;
            }
        }else {
            // 计价器3.0订单
            Integer masterAmount = orderWork.getMasterAmount();
            if (masterAmount+otherDiscountAmount < discountAmount){
                return masterAmount+otherDiscountAmount;
            }
            return discountAmount;
        }
    }


    private void commonVerify(OrderWork orderWork) throws OmsBaseException {
        if (orderWork == null) {
            throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
        }
        if (orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_VISIT) {
            throw new OmsBaseException(OmsErrorCodeConsts.STATUS_NOT_LEGAL, "订单未上门，不可操作");
        }
        if (orderWork.getStatus() > OrderStatusConsts.WORK_STATUS_COMPLETE) {
            throw new OmsBaseException(OmsErrorCodeConsts.STATUS_NOT_LEGAL, "订单已完成，不可操作");
        }
        if (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_FAIL)
                || Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DISCARD)) {
            throw new OmsBaseException(OmsErrorCodeConsts.STATUS_NOT_LEGAL, "订单已取消，不可操作");
        }
    }

    /**
     * 校验配件
     * @param orderWork
     * @param itemIdList
     * @throws OmsBaseException
     */
    private void verifyPart(OrderWork orderWork, List<Integer> itemIdList) throws OmsBaseException {
        if (!Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            return;
        }

        if (NumberUtil.isNullOrZero(orderWork.getPartUse())) {
            throw new OmsBaseException("请选择是否需要使用配件");
        }

        if (CollectionUtil.isNullOrEmpty(itemIdList)) {
            return;
        }

        log.info("serviceItemListRemoteService.getItemPartByItemId serviceItemIdList={}", itemIdList);
        ResponseDTO<List<ItemPartsDRO>> responseDTO = itemPartsRemoteService.listItemPartByItemIds(itemIdList);
        log.info("serviceItemListRemoteService.getItemPartByItemId responseDTO={}", JSON.toJSONString(responseDTO));
        if (!responseDTO.isSuccess()) {
            throw new OmsBaseException(responseDTO.getMessage());
        }

        if (CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
            return;
        }

        // 内采
        boolean notInPart = false;
        SingleMasterOrderPartDTO singleMasterOrderPartDTO = orderPartBService.listByOrderIdAndMaster(orderWork.getOrderId(), orderWork.getMasterId());
        if (CollectionUtil.isNullOrEmpty(singleMasterOrderPartDTO.getInParts())) {
            notInPart = true;
        }

        // 外报
        boolean notOutPart = false;
        ScmPurchaseApplyQuery scmPurchaseFreightQuery = new ScmPurchaseApplyQuery();
        scmPurchaseFreightQuery.setSourceId(String.valueOf(orderWork.getWorkId()));
        ResponseDTO<List<ScmPurchaseApplyDRO>> listResponseDTO = engineerPurchaseListRemoteService.listByQueryV2(scmPurchaseFreightQuery);
        if (CollectionUtil.isNullOrEmpty(listResponseDTO.getData())) {
            notOutPart = true;
        }

        if (notInPart && notOutPart) {
            throw new OmsBaseException("服务含配件，请选择配件");
        }

    }

    private Integer generateOrderAmount(OmsOperator operator, OrderWork orderWork, List<Integer> itemIdList) throws OmsBaseException {
        if (Objects.isNull(orderWork)) {
            orderWork = orderWorkService.findOrderWorkByKey(operator.getOrderId(), operator.getWorkId());
            if (orderWork == null) {
                return null;
            }
        }

        List<OrderProductExtend> extendList = orderProductExtendService.listByOrderId(operator.getOrderId());

        Long proExtId = extendList.get(0).getProExtId();

        AddOrderServiceItemDTO addOrderServiceItemDTO = new AddOrderServiceItemDTO();
        addOrderServiceItemDTO.setOrderId(operator.getOrderId());
        addOrderServiceItemDTO.setWorkId(operator.getWorkId());
        addOrderServiceItemDTO.setProExtId(proExtId);
        addOrderServiceItemDTO.setQuotationType(operator.getOperatorType());
        addOrderServiceItemDTO.setIsProductChanged(false);
        addOrderServiceItemDTO.setServItemType(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);

        OrderProduct orderProduct = orderProductService.listOrderProductByOrderId(operator.getOrderId()).get(0);
        List<Integer> serviceItemIdList;
        if (CollectionUtil.isNullOrEmpty(itemIdList)) {
            List<OrderQuotationServiceItem> quotationServiceItemList = orderquotationserviceitemService.listByOrderId(operator.getOrderId());

            if (CollectionUtil.isNullOrEmpty(quotationServiceItemList)) {
                throw new OmsBaseException(OmsErrorCodeConsts.STATUS_NOT_LEGAL, "无报价服务项");
            }
            serviceItemIdList = quotationServiceItemList.stream().map(OrderQuotationServiceItem::getItemId).collect(Collectors.toList());
        } else {
            serviceItemIdList = itemIdList;
        }

        // 处理服务项
        ItemQuoteQuery quoteQuery3 = ItemQuoteQuery.builder()
                .bizType(orderWork.getBizType())
                .channelId(orderWork.getChannelId())
                .cityId(orderWork.getCityId())
                .productId(orderWork.getProductId())
                .brandId(orderProduct.getBrandId())
                .tariffId(orderProduct.getTariffId())
                .itemList(serviceItemIdList).build();
        ResponseDTO<List<ItemDRO>> itemResponseDTO = itemPriceRemoteService.listItemQuoteByQuery(quoteQuery3);
        log.info("计价器工单确认检测报告获取服务项：入参：{} 出参：{}", JSON.toJSONString(quoteQuery3), JSON.toJSONString(itemResponseDTO));
        if (!itemResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(itemResponseDTO.getData())) {
            throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, itemResponseDTO.getMessage());
        }
        List<ItemDRO> itemDRO3List = itemResponseDTO.getData();
        ItemDRO item = itemDRO3List.stream().max(Comparator.comparing(ItemDRO::getPrice)).get();

        OrderServiceItem serviceItem = new OrderServiceItem();
        serviceItem.setServItemId(item.getItemId());
        serviceItem.setServItemName(item.getItemName());
        serviceItem.setInternalSettlementPrice(item.getPriceInternalSettlement());
        serviceItem.setInternalTotalPrice(item.getPriceInternalSettlement());
        serviceItem.setExternalSettlementPrice(item.getPriceExternalSettlement());
        serviceItem.setExternalTotalPrice(item.getPriceExternalSettlement());
        serviceItem.setItemPrice(item.getPrice());
        serviceItem.setTotalPrice(item.getPrice());
        serviceItem.setProductId(orderProduct.getProductId());
        serviceItem.setProductName(orderProduct.getProductName());
        serviceItem.setOrderId(operator.getOrderId());
        serviceItem.setNumber(1);
        serviceItem.setProExtId(proExtId);
        serviceItem.setServItemGroupId(item.getItemTypeId());
        serviceItem.setServItemGroupName(Optional.ofNullable(item.getItemTypeName()).orElse("默认值"));
        serviceItem.setServItemCategId(item.getItemTypeId());
        serviceItem.setTieredTotalPrice(item.getPrice());
        serviceItem.setOrigItemPrice(item.getPrice());
        serviceItem.setOrigTotalPrice(item.getPrice());
        serviceItem.setCreater(operator.getOperator());
        serviceItem.setCreateTime(DateUtil.getNow());


        if (CollectionUtil.isNotNullOrEmpty(item.getItemCellList())) {
            List<OrderServiceItemCell> itemCellList = new ArrayList<>(item.getItemCellList().size());
            for (ItemCellDRO itemCell : item.getItemCellList()) {
                OrderServiceItemCell cell = new OrderServiceItemCell();
                cell.setItemCellId(itemCell.getItemCellId());
                cell.setItemCellName(itemCell.getItemCellName());
                cell.setCellPrice(itemCell.getCellPrice());
                cell.setSort(itemCell.getSort());
                cell.setCreater(operator.getOperator());
                cell.setCreateTime(DateUtil.getNow());
                itemCellList.add(cell);
            }
            serviceItem.setItemDetailList(itemCellList);
        }
        addOrderServiceItemDTO.setOrderServiceItemList(Lists.newArrayList(serviceItem));
        Integer discount = zsNormalOrderServiceItemBService.getDiscount(addOrderServiceItemDTO);

        return discount;
    }



    private OrderAmountDRO getOrderAmount2(Long orderId, Long workId, Integer discountAmount) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException(OmsErrorCodeConsts.ORDER_NOT_FOUND, "订单不存在");
        }

        OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderId);

        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

        List<Integer> itemTypeIds;
        if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE);
        } else {
            itemTypeIds = servItemBService.getServItemTypeIdList(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
        }
        Optional<OrderServiceItem> maintainServiceItemOptional = orderServiceItemList.stream().filter(item ->
                itemTypeIds.contains(item.getServItemGroupId())).findFirst();
        OrderAmountDRO orderAmountDRO = new OrderAmountDRO();

        if (maintainServiceItemOptional.isPresent() && !Objects.equals(process.getAgreeStatus(), GlobalConsts.NO)) {
            // 已有价格
            OrderServiceItem serviceItem = maintainServiceItemOptional.get();
            List<OrderServiceItemCell> orderServiceItemDetails = orderServiceItemCellDao.listByOrderIdAndServItemId(orderId, workId, serviceItem.getServItemId());
            // 增值服务项价格
            List<Integer> additionalServiceTypeIdList = new ArrayList<>();
            if (Objects.equals(orderWork.getFinalPrice(), com.zmn.consts.GlobalConsts.YES)) {
                additionalServiceTypeIdList.add(ItemTypeConst.EXTRA_ITEM);
            } else {
                additionalServiceTypeIdList.add(ItemTypeConst.ADDITION_ITEM);
            }
            Integer additionalItemAmount = orderServiceItemList.stream().filter(item -> additionalServiceTypeIdList.contains(item.getServItemGroupId())).mapToInt(OrderServiceItem::getTotalPrice).sum();

            if (CollectionUtil.isNotNullOrEmpty(orderServiceItemDetails)) {
                List<OrderAmountDetailDRO> detailDROS = new ArrayList<>(orderServiceItemDetails.size());
                for (OrderServiceItemCell orderServiceItemDetail : orderServiceItemDetails) {
                    OrderAmountDetailDRO detailDRO = new OrderAmountDetailDRO();
                    detailDRO.setItemCellId(orderServiceItemDetail.getItemCellId());
                    detailDRO.setItemCellName(orderServiceItemDetail.getItemCellName());
                    detailDRO.setCellPrice(orderServiceItemDetail.getCellPrice());
                    detailDROS.add(detailDRO);
                    // 兼容老包
                    switch (orderServiceItemDetail.getItemCellId()) {
                        case ItemCellConst.ITEM_CELL_PART:
                            orderAmountDRO.setPartPrice(orderServiceItemDetail.getCellPrice());
                            break;
                        case ItemCellConst.ITEM_CELL_HOUR:
                            orderAmountDRO.setHourFee(orderServiceItemDetail.getCellPrice());
                            break;
                        case ItemCellConst.ITEM_CELL_TRIP:
                            orderAmountDRO.setTrafficFee(orderServiceItemDetail.getCellPrice());
                            break;
                    }
                }
                orderAmountDRO.setDetailList(detailDROS);
            }
            Integer payDiscountAmount = orderWork.getPayDiscountAmount();

            // 处理已付金额
            Integer factAmount = orderAmountBService.getOrderWorkFactAmount(orderWork);

            List<OrderDiscount> discounts = orderDiscountService.listByOrderIdSrcMaster(orderId);
            if (!Objects.isNull(discountAmount)) {
                if (Objects.equals(orderWork.getFinalPrice(), GlobalConsts.YES)) {
                    ArtificialPromDIO dio = ArtificialPromDIO.builder()
                            .tariffType(OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE)
                            .orderId(orderWork.getOrderId())
                            .channelId(orderWork.getChannelId())
                            .cityId(orderWork.getCityId())
                            .productId(orderWork.getShowProductId())
                            .artificialDiscountAmount(discountAmount)
                            .orderAmount(orderWork.getOriginalAmount())
                            .paidPrice(factAmount)
                            .usedDiscountAmount(orderWork.getDiscountAmount())
                            .build();
                    log.info("[{}]计价器3.0调用优惠计算接口：入参：{}", orderId, dio);
                    ResponseDTO<Integer> amountResponse = orderAmountRemoteService.getDiscount(dio);
                    log.info("[{}]计价器3.0调用优惠计算接口：出参：{}", orderId, amountResponse);
                    if (!amountResponse.isSuccess()) {
                        throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, "计算优惠失败");
                    }
                    orderAmountDRO.setTotalFee(amountResponse.getData());
                    orderAmountDRO.setRemainingReceivableAmount(amountResponse.getData() - factAmount);
                    return orderAmountDRO;
                } else {
                    // 此时工程师操作请求优惠，需要根据人工优惠ID实时计算
                    Integer useDlaborPreferenceAmount = discounts.stream().filter(discount -> Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL)).mapToInt(OrderDiscount::getAmount).sum();
                    Integer beforeLaborPreferenceAmount = orderWork.getTotalAmount() + useDlaborPreferenceAmount;

                    ArtificialPromDIO dio = ArtificialPromDIO.builder()
                            .tariffType(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)
                            .channelId(orderWork.getChannelId())
                            .cityId(orderWork.getCityId())
                            .productId(orderWork.getShowProductId())
                            .artificialDiscountAmount(discountAmount)
                            .orderAmount(beforeLaborPreferenceAmount)
                            .paidPrice(factAmount)
                            .build();
                    log.info("[{}]计价器3.0调用优惠计算接口：入参：{}", orderId, dio);
                    ResponseDTO<Integer> amountResponse = orderAmountRemoteService.getDiscount(dio);
                    log.info("[{}]计价器3.0调用优惠计算接口：出参：{}", orderId, amountResponse);
                    if (!amountResponse.isSuccess()) {
                        throw new OmsBaseException(OmsErrorCodeConsts.CALL_THIRED_SYS_FAILED, "计算优惠失败");
                    }
                    orderAmountDRO.setTotalFee(amountResponse.getData());
                    orderAmountDRO.setRemainingReceivableAmount(amountResponse.getData() - factAmount);
                    return orderAmountDRO;
                }
            }
            if (CollectionUtil.isNotNullOrEmpty(discounts)) {
                Integer coupDiscountAmount = discounts.stream().filter(discount -> Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON) || Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_CASH_COUPON)).mapToInt(OrderDiscount::getAmount).sum();
                Integer otherDiscountAmount = discounts.stream().filter(discount -> !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON) && !Objects.equals(discount.getCateg(), DiscountConsts.DISCOUNT_CATEG_CASH_COUPON)).mapToInt(OrderDiscount::getAmount).sum();

                orderAmountDRO.setCoupDiscountAmount(coupDiscountAmount);
                orderAmountDRO.setOtherDiscountAmount(otherDiscountAmount);
            }
            orderAmountDRO.setDepositAmount(factAmount);
            orderAmountDRO.setTotalFee(orderWork.getTotalAmount() - factAmount - additionalItemAmount);
            orderAmountDRO.setRemainingReceivableAmount(orderWork.getTotalAmount() - factAmount);
            orderAmountDRO.setServItemPrice(serviceItem.getTotalPrice());
            orderAmountDRO.setServItemName(serviceItem.getServItemName());
            orderAmountDRO.setPayDiscountAmount(payDiscountAmount);
        } else {
            // 没有价格
            orderAmountDRO = orderAmountBService.getQuotationOrderAmountByOrderIdAndWorkId(orderId, workId, null);
        }

        // 一口价下单参数
        this.setfinalPriceOrderExtDRO(orderWork, orderAmountDRO);
        this.setServChargePromptStr(orderWork, orderAmountDRO, process, orderServiceItemList);

        return orderAmountDRO;
    }
}
